use evdev_rs::enums::{EventCode, EventType, EV_KEY, EV_REL};
use evdev_rs::{Device, InputEvent};
use evdev_rs::{GrabMode, ReadFlag, TimeVal};
use mouse_keyboard_input::{VirtualDevice, BTN_EXTRA, BTN_LEFT, BTN_MIDDLE, BTN_RIGHT, KEY_ESC, KEY_F10, KEY_F4, KEY_LEFTALT, KEY_LEFTMETA};

// 可以安装 evtest 软件来找出鼠标是哪个设备：sudo pacman -S evtest
// 然后使用root权限运行evtest工具：sudo evtest

const KEY_PRESSED: i32 = 1;
const KEY_RELEASED: i32 = 0;

fn find_mouse_device() ->String{
    let exe_path = std::env::current_exe().unwrap();
    let config_file_path = exe_path.parent().unwrap().join("mouse.config").to_str().unwrap().to_string();
    let config = std::fs::read_to_string(config_file_path).unwrap();
    let lines: Vec<&str> = config.split('\n').collect();
    let mut iter = lines.iter().filter(|line| line.starts_with("mouse-device="));
    iter.next().unwrap().split('=').skip(1).next().unwrap().to_string()
}

fn main() {
    let device_path = find_mouse_device();
    let mut mouse_device = Device::new_from_path(device_path).unwrap();
    // 独占设备
    mouse_device.grab(GrabMode::Grab).unwrap();

    // 虚拟输入设备，用来模拟输入
    let mut virtual_input_device = VirtualDevice::default().unwrap();

    let mut previous_key_event: Option<InputEvent> = None;
    let mut previous_rel_events: Vec<InputEvent> = vec![];

    // 是否处于激活状态
    // 当鼠标的左后方的侧键（BTN_SIDE）被按下，那么进入激活状态，直至此键被松开
    let mut in_active_state = false;

    let mut left_alt_pressed = false;

    // 上一次敲击ESC键的时间
    let mut last_click_esc_time: TimeVal = TimeVal { tv_sec: 0, tv_usec: 0 };
    loop {
        let ev = mouse_device.next_event(ReadFlag::NORMAL).map(|val| val.1);
        match ev {
            Ok(ev) => {
                if let Some(event_type) = ev.event_type() {
                    if event_type == EventType::EV_KEY {
                        // 按键事件 (Key Events - EV_KEY)
                        
                        // ev.code用于判断是哪个键
                        // ev.value用于判断是按下还是释放
                        if ev.event_code == EventCode::EV_KEY(EV_KEY::BTN_SIDE) {
                            if ev.value == KEY_PRESSED {
                                in_active_state = true;
                                println!("进入激活状态");

                            } else if ev.value == KEY_RELEASED {
                                in_active_state = false;
                                println!("退出激活状态");

                                if let Some(previous_ev) = previous_key_event {
                                    // 如果上一个事件是BTN_SIDE被按下，当前事件是BTN_SIDE被松开，那么模拟SUPER_L被按下并松开事件
                                    if previous_ev.value == KEY_PRESSED && previous_ev.event_code == EventCode::EV_KEY(EV_KEY::BTN_SIDE) {
                                        // 模拟SUPER_L被按下并被松开
                                        // 在 Linux 系统中，键盘上的 Win 键最常被称为 Super 键或者 Meta 键。
                                        println!("模拟Super_L被按下并松开");
                                        virtual_input_device.click(KEY_LEFTMETA).unwrap();
                                    }
                                }

                                // 如果上一个事件是鼠标滚轮事件，当前事件是BTN_SIDE被松开，那么模拟Alt键被松开事件
                                if left_alt_pressed {
                                    println!("模拟KEY_LEFTALT被松开");
                                    virtual_input_device.release(KEY_LEFTALT).unwrap();
                                    left_alt_pressed = false;
                                }
                            }
                        }else {
                            if in_active_state {
                                // 在激活状态下，当点击鼠标左键时，模拟Alt+F10（用来切换窗口的最大化/最小化状态）
                                // 在激活状态下，当点击鼠标右键时，模拟Alt+F4（用来关闭窗口）
                                match ev.event_code {
                                    EventCode::EV_KEY(EV_KEY::BTN_LEFT) => {
                                        if ev.value == KEY_RELEASED {
                                            println!("在激活状态下，当点击鼠标左键时，模拟Alt+F10（用来切换窗口的最大化/最小化状态）");
                                            virtual_input_device.press(KEY_LEFTALT).unwrap();
                                            virtual_input_device.press(KEY_F10).unwrap();
                                            virtual_input_device.release(KEY_F10).unwrap();
                                            virtual_input_device.release(KEY_LEFTALT).unwrap();
                                        }
                                    },
                                    EventCode::EV_KEY(EV_KEY::BTN_RIGHT) => {
                                        if ev.value == KEY_RELEASED {
                                            println!("在激活状态下，当点击鼠标右键时，模拟Alt+F4（用来关闭窗口）");
                                            virtual_input_device.press(KEY_LEFTALT).unwrap();
                                            virtual_input_device.press(KEY_F4).unwrap();
                                            virtual_input_device.release(KEY_F4).unwrap();
                                            virtual_input_device.release(KEY_LEFTALT).unwrap();
                                        }
                                    },
                                    _ => ()
                                };

                            } else {
                                // 原样发送按键
                                let option_key = match ev.event_code {
                                    EventCode::EV_KEY(EV_KEY::BTN_EXTRA) => Some(BTN_EXTRA),
                                    EventCode::EV_KEY(EV_KEY::BTN_LEFT) => Some(BTN_LEFT),
                                    EventCode::EV_KEY(EV_KEY::BTN_RIGHT) => Some(BTN_RIGHT),
                                    EventCode::EV_KEY(EV_KEY::BTN_MIDDLE) => Some(BTN_MIDDLE),
                                    _ => None
                                };
                                if option_key.is_none() {
                                    continue;
                                }
                                let key = option_key.unwrap();
                                if ev.value == KEY_PRESSED {
                                    virtual_input_device.press(key).unwrap();
                                } else if ev.value == KEY_RELEASED {
                                    virtual_input_device.release(key).unwrap();
                                }
                            }
                        }

                        // 记录事件
                        previous_key_event = Some(ev);
                    } else if event_type == EventType::EV_REL {
                        // 相对移动事件 (Relative Movement Events - EV_REL)

                        if in_active_state && (ev.event_code == EventCode::EV_REL(EV_REL::REL_WHEEL) ||
                            ev.event_code == EventCode::EV_REL(EV_REL::REL_WHEEL_HI_RES)){
                            // 在激活状态下，当滚动鼠标滚轮时，模拟Alt+ESC（用来依次切换窗口）
                            println!("在激活状态下，当滚动鼠标滚轮时，模拟Alt+ESC（用来依次切换窗口）");
                            if !left_alt_pressed {
                                // 按下KEY_LEFTALT键，当松开鼠标侧键（BTN_SIDE）的时候，需要记得松开KEY_LEFTALT键
                                virtual_input_device.press(KEY_LEFTALT).unwrap();
                                left_alt_pressed = true;

                                virtual_input_device.click(KEY_ESC).unwrap();
                                last_click_esc_time = ev.time;

                                // 清除previous_ev，避免松开BTN_SIDE的时候模拟Super_L
                                previous_key_event = None;
                            }

                            // 如果间隔时间太短，那么忽略本次滚轮事件，避免窗口切换太频繁
                            let duration_in_milli_secs = (ev.time.tv_sec - last_click_esc_time.tv_sec) * 1000 + (ev.time.tv_usec - last_click_esc_time.tv_usec) / 1000;
                            if(duration_in_milli_secs < 500){
                                continue;
                            }
                            virtual_input_device.click(KEY_ESC).unwrap();
                            last_click_esc_time = ev.time;
                        } else {
                            previous_rel_events.push(ev);
                        }
                    } else if event_type == EventType::EV_SYN {
                        if !previous_rel_events.is_empty() {
                            for rel_ev in &previous_rel_events {
                                if rel_ev.event_code == EventCode::EV_REL(EV_REL::REL_X) {

                                    println!("鼠标 沿 X 轴（水平）的相对位移量: {}", rel_ev.value);
                                    virtual_input_device.move_mouse_x(rel_ev.value).unwrap();

                                } else if rel_ev.event_code == EventCode::EV_REL(EV_REL::REL_Y) {

                                    println!("沿 Y 轴（垂直）的相对位移量: {}", rel_ev.value);
                                    virtual_input_device.move_mouse_y(-rel_ev.value).unwrap();

                                } else if rel_ev.event_code == EventCode::EV_REL(EV_REL::REL_WHEEL) {

                                    println!("滚轮事件REL_WHEEL，相对偏移量: {}", rel_ev.value);
                                    virtual_input_device.scroll_y(rel_ev.value).unwrap();

                                } else if rel_ev.event_code == EventCode::EV_REL(EV_REL::REL_WHEEL_HI_RES) {

                                    println!("滚轮事件REL_WHEEL_HI_RES，相对偏移量: {}", rel_ev.value);
                                    virtual_input_device.scroll_y(rel_ev.value).unwrap()

                                }
                            }
                            previous_rel_events.clear();
                        }
                    }
                }
            },
            Err(_e) => {
                // println!("出现错误:{e}")
            },
        }
    }
}
